﻿//========================================================= 
/**@file PSBC_PinCmdDriver.h
 * @brief 邮储国密键盘驱动
 * 
 * @date 2016-04-02   18:07:39
 * @author Zhyioo 
 * @version 1.0
 */ 
//--------------------------------------------------------- 
#ifndef _LIBZHOUYB_PSBC_PINCMDDRIVER_H_
#define _LIBZHOUYB_PSBC_PINCMDDRIVER_H_
//--------------------------------------------------------- 
#include "../CommonCmdDriver.h"

#include "../../../extension/security/Key_Provider.h"
using zhou_yb::extension::security::Key_Provider;

#include "../../pinpad/PSBC_PinPadDevAdapter.h"
using zhou_yb::application::pinpad::PSBC_PinDesDevAdapter;
using zhou_yb::application::pinpad::PSBC_PinSm4DevAdapter;
using zhou_yb::application::pinpad::PSBC_PinPadDevAdapter;
using zhou_yb::application::pinpad::PSBC_PinManagerDevAdapter;
//--------------------------------------------------------- 
namespace zhou_yb {
namespace application {
namespace driver {
//--------------------------------------------------------- 
/// 邮储国密键盘命令驱动
class PSBC_PinCmdDriver : 
    public CommonCmdDriver, 
    public BaseDevAdapterBehavior<IInteractiveTrans>
{
public:
    static void FormatInput(byte key, ByteBuilder& input)
    {
        switch(key)
        {
        case 0x0D:
            input += "Enter";
            break;
            // 00
        case 0x4F:
            input += "00";
            break;
            // .
        case 0x2E:
            input += ".";
            break;
            // cancel
        case 0x1B:
            input += "Cancel";
            break;
            // correct
        case 0x08:
            input += "Correct";
            break;
        case 0x2A:
        case 0x4E:
            input += "*";
            break;
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
        case '0':
            input += key;
            break;
        default:
            break;
        }
    }
protected:
    DevAdapterSetter<IInteractiveTrans> _devSetter;
    ComICCardCmdAdapter _cmdAdapter;
    PinDevCmdAdapter _pinCmdAdapter;
    PSBC_PinSm4DevAdapter _sm4Adapter;
    PSBC_PinDesDevAdapter _desAdapter;
    PSBC_PinPadDevAdapter _guomiAdapter;
    PSBC_PinManagerDevAdapter _managerAdapter;
public:
    PSBC_PinCmdDriver() : CommonCmdDriver()
    {
        _errGetter.Add("SM4", _sm4Adapter)
            .Add("DES", _desAdapter)
            .Add("GuoMi", _guomiAdapter)
            .Add("Manager", _managerAdapter);

        select_helper<LoggerSetter::SelecterType>::select(_logSetter),
            _cmdAdapter, _sm4Adapter, _desAdapter, _guomiAdapter, _managerAdapter;
        select_helper<DevAdapterSetter<IInteractiveTrans>::SelecterType>::select(_devSetter),
            _cmdAdapter, _pinCmdAdapter;

        _sm4Adapter.SelectDevice(_pinCmdAdapter);
        _desAdapter.SelectDevice(_pinCmdAdapter);
        _guomiAdapter.SelectDevice(_cmdAdapter);
        _managerAdapter.SelectDevice(_pinCmdAdapter);

        _RegisteCMD(PSBC_PinCmdDriver, ResetMK);
        _RegisteCMD(PSBC_PinCmdDriver, ResetKey);
        _RegisteCMD(PSBC_PinCmdDriver, UpdateMainKey);
        _RegisteCMD(PSBC_PinCmdDriver, SetPinLength);
        _RegisteCMD(PSBC_PinCmdDriver, DownloadMK);
        _RegisteCMD(PSBC_PinCmdDriver, DownloadWK);
        _RegisteCMD(PSBC_PinCmdDriver, WaitPassword_Ansi98);
        _RegisteCMD(PSBC_PinCmdDriver, GetPassword_Ansi98);
        _RegisteCMD(PSBC_PinCmdDriver, Evaluation);
        _RegisteCMD(PSBC_PinCmdDriver, GenerateKEY);
        _RegisteCMD(PSBC_PinCmdDriver, GeneratePIN);
        _RegisteCMD(PSBC_PinCmdDriver, WaitEntry);
        _RegisteCMD(PSBC_PinCmdDriver, GetAppNumber);
        _RegisteCMD(PSBC_PinCmdDriver, SetAppNumber);
        _RegisteCMD(PSBC_PinCmdDriver, GetMK_ID);
        _RegisteCMD(PSBC_PinCmdDriver, SetMK_ID);

        _RegisteAdapterCMD(PSBC_PinCmdDriver);
    }
    LC_CMD_ADAPTER_INVOKE(IInteractiveTrans, _devSetter);
    /**
     * @brief 初始化密钥为指定值
     * 
     * @param [in] Algorithm : string 算法标识
     * - 参数:
     *  - DES
     *  - SM4
     * .
     * @param [in] MkIndex : byte 主密钥索引
     * @param [in] Key : hex 重置的新密钥
     */
    LC_CMD_METHOD(ResetMK)
    {
        string algorithm = arg["Algorithm"].To<string>();
        byte mkIndex = arg["MkIndex"].To<byte>();
        string key = arg["Key"].To<string>();

        ByteBuilder keyBuff(16);
        DevCommand::FromAscii(key.c_str(), keyBuff);
        // 重置DES所有密钥
        if(StringConvert::Compare(algorithm.c_str(), "DES", true))
        {
            if(!_desAdapter.ResetMK(mkIndex, keyBuff))
                return false;
        }
        else if(StringConvert::Compare(algorithm.c_str(), "SM4", true))
        {
            if(!_sm4Adapter.ResetMK(mkIndex, keyBuff))
                return false;
        }
        else
        {
            _logErr(DeviceError::ArgFormatErr, "错误的算法标识");
            return false;
        }
        return true;
    }
    /**
     * @brief 恢复密钥为出厂设置
     * 
     * @param [in] Algorithm : string 算法标识
     * - 参数:
     *  - DES
     *  - SM4
     * .
     * @param [in] MkIndex : byte 主密钥索引
     */
    LC_CMD_METHOD(ResetKey)
    {
        string algorithm = arg["Algorithm"].To<string>();
        byte mkIndex = arg["MkIndex"].To<byte>();

        // 重置DES所有密钥
        if(StringConvert::Compare(algorithm.c_str(), "DES", true))
        {
            if(!_desAdapter.ResetKey(mkIndex))
                return false;
        }
        else if(StringConvert::Compare(algorithm.c_str(), "SM4", true))
        {
            if(!_sm4Adapter.ResetKey(mkIndex))
                return false;
        }
        else
        {
            _logErr(DeviceError::ArgFormatErr, "错误的算法标识");
            return false;
        }
        return true;
    }
    /**
     * @brief 明文修改主密钥
     * 
     * @param [in] Algorithm : string 算法标识
     * - 参数:
     *  - DES
     *  - SM4
     * .
     * @param [in] MkIndex : byte 主密钥索引
     * @param [in] OldKey : hex 原来的主密钥明文
     * @param [in] NewKey : hex 重置的新密钥明文
     */
    LC_CMD_METHOD(UpdateMainKey)
    {
        string algorithm = arg["Algorithm"].To<string>();
        byte mkIndex = arg["MkIndex"].To<byte>();
        string oldKey = arg["OldKey"].To<string>();
        string newKey = arg["NewKey"].To<string>();

        ByteBuilder oldKeyBuff(16);
        DevCommand::FromAscii(oldKey.c_str(), oldKeyBuff);

        ByteBuilder newKeyBuff(16);
        DevCommand::FromAscii(newKey.c_str(), newKeyBuff);

        // 重置DES所有密钥
        if(StringConvert::Compare(algorithm.c_str(), "DES", true))
        {
            if(!_desAdapter.UpdateMainKey(mkIndex, oldKeyBuff, newKeyBuff))
                return false;
        }
        else if(StringConvert::Compare(algorithm.c_str(), "SM4", true))
        {
            if(!_sm4Adapter.UpdateMainKey(mkIndex, oldKeyBuff, newKeyBuff))
                return false;
        }
        else
        {
            _logErr(DeviceError::ArgFormatErr, "错误的算法标识");
            return false;
        }
        return true;
    }
    /**
     * @brief 设置输入的密码长度
     *
     * @param [in] Length : size_t 需要设置的输入长度
     */
    LC_CMD_METHOD(SetPinLength)
    {
        size_t len = arg["Length"].To<size_t>();
        // 设置密码长度
        ByteBuilder tmp(2);
        _managerAdapter.SetPinLength(_itobyte(len));
        if(!_pDev->Read(tmp) || tmp.GetLength() < 1 || tmp[0] != 0xAA)
        {
            _logErr(DeviceError::RecvErr);
            return false;
        }
        return true;
    }
    /**
     * @brief 密文下载主密钥
     * 
     * @param [in] Algorithm : string 算法标识
     * - 参数:
     *  - DES
     *  - SM4
     *  - AUTO
     * .
     * @param [in] MkIndex : byte 主密钥索引
     * @warning 算法为[AUTO]时该参数为13字符以内的密钥ID
     *
     * @param [in] KEY : hex 主密钥密文
     * @param [in] KCV : hex 主密钥KCV
     */
    LC_CMD_METHOD(DownloadMK)
    {
        string algorithm = arg["Algorithm"].To<string>();
        string keyId = arg["MkIndex"].To<string>();
        string key = arg["KEY"].To<string>();
        string kcv = arg["KCV"].To<string>();

        ByteBuilder keyBuff(16);
        ByteBuilder kcvBuff(16);

        DevCommand::FromAscii(key.c_str(), keyBuff);
        DevCommand::FromAscii(kcv.c_str(), kcvBuff);

        if(StringConvert::Compare(algorithm.c_str(), "DES", true))
        {
            byte mkIndex = ArgConvert::FromString<byte>(keyId);
            if(!_desAdapter.UpdateEncryptedMainKey(mkIndex, keyBuff, kcvBuff))
                return false;
        }
        else if(StringConvert::Compare(algorithm.c_str(), "SM4", true))
        {
            byte mkIndex = ArgConvert::FromString<byte>(keyId);
            if(!_sm4Adapter.UpdateEncryptedMainKey(mkIndex, keyBuff, kcvBuff))
                return false;
        }
        else if(StringConvert::Compare(algorithm.c_str(), "AUTO", true))
        {
            const size_t MAC_KEYID_LENGTH = 13;
            ByteBuilder mkId(MAC_KEYID_LENGTH);
            mkId = keyId.c_str();
            ByteConvert::Fill(mkId, MAC_KEYID_LENGTH, false, '0');
            // 设置主密钥ID
            if(!_guomiAdapter.SetMK_ID(mkId))
                return false;
            if(!_guomiAdapter.DownloadMK(keyBuff, mkId, kcvBuff))
                return false;
        }
        else
        {
            _logErr(DeviceError::ArgFormatErr, "错误的算法标识");
            return false;
        }
        return true;
    }
    /**
     * @brief 密文下载工作密钥
     * 
     * @param [in] Algorithm : string 算法标识
     * - 参数:
     *  - DES
     *  - SM4
     *  - AUTO
     * .
     * @param [in] MkIndex : byte 主密钥索引
     * @param [in] WkIndex : byte 工作密钥索引
     * @param [in] KEY : hex 工作密钥密文
     * @param [in] KCV : hex 工作密钥KCV
     * 
     * @retval KCV : hex 返回的KCV 
     * @warning Algorithm为[AUTO]时,KCV为空则设备生成KCV返回
     */
    LC_CMD_METHOD(DownloadWK)
    {
        string algorithm = arg["Algorithm"].To<string>();
        string sMkIndex = arg["MkIndex"].To<string>();
        string sWkIndex = arg["WkIndex"].To<string>();
        string key = arg["KEY"].To<string>();
        string kcv = arg["KCV"].To<string>();

        ByteBuilder keyBuff(16);
        ByteBuilder kcvBuff(16);

        DevCommand::FromAscii(key.c_str(), keyBuff);
        DevCommand::FromAscii(kcv.c_str(), kcvBuff);

        if(StringConvert::Compare(algorithm.c_str(), "DES", true))
        {
            byte mkIndex = ArgConvert::FromString<byte>(sMkIndex);
            byte wkIndex = ArgConvert::FromString<byte>(sWkIndex);
            if(!_desAdapter.UpdateEncryptedWorkKey(mkIndex, wkIndex, keyBuff, kcvBuff))
                return false;
        }
        else if(StringConvert::Compare(algorithm.c_str(), "SM4", true))
        {
            byte mkIndex = ArgConvert::FromString<byte>(sMkIndex);
            byte wkIndex = ArgConvert::FromString<byte>(sWkIndex);
            if(!_sm4Adapter.UpdateEncryptedWorkKey(mkIndex, wkIndex, kcvBuff, kcvBuff))
                return false;
        }
        else if(StringConvert::Compare(algorithm.c_str(), "AUTO", true))
        {
            const size_t MAC_KEYID_LENGTH = 13;
            ByteBuilder keyId(MAC_KEYID_LENGTH);
            // 设置主密钥ID
            keyId = sMkIndex.c_str();
            ByteConvert::Fill(keyId, MAC_KEYID_LENGTH, false, '0');
            if(!_guomiAdapter.SetMK_ID(keyId))
                return false;
            // 设置工作密钥ID
            keyId = sWkIndex.c_str();
            ByteConvert::Fill(keyId, MAC_KEYID_LENGTH, false, '0');
            if(!_guomiAdapter.SetWK_ID(keyId))
                return false;
            // KCV为空则设备返回一个KCV
            if(kcvBuff.IsEmpty())
            {
                if(!_guomiAdapter.DownloadWK_KCV(keyBuff, keyId, &kcvBuff))
                    return false;
                ByteBuilder tmp(8);
                ByteConvert::ToAscii(kcvBuff, tmp);
                rlt.Put("KCV", tmp.GetString());
            }
            else
            {
                if(!_guomiAdapter.DownloadWK(keyBuff, keyId, kcvBuff))
                    return false;
            }
        }
        else
        {
            _logErr(DeviceError::ArgFormatErr, "错误的算法标识");
            return false;
        }
        return true;
    }
    /**
     * @brief 使用主密钥加密数据
     * @date 2016-11-15 21:23
     * 
     * @param [in] Algorithm : string 算法标识
     * - 参数:
     *  - DES
     *  - SM4
     * .
     * @param [in] MKIndex : byte 加密数据的主密钥索引
     * @param [in] IV : hex 加密数据的向量
     * @param [in] DATA : hex 需要加密的数据
     * 
     * @retval DATA : hex 加密后的数据 
     * @retval KeyLength : size_t 加密数据的密钥长度
     */
    LC_CMD_METHOD(MKeyEncrypt)
    {
        string algorithm = arg["Algorithm"].To<string>();
        byte mkIndex = arg["MkIndex"].To<byte>();
        string sIV = arg["IV"].To<string>();
        string sData = arg["DATA"].To<string>();

        ByteBuilder iv(8);
        ByteBuilder buff(16);

        return true;
    }
    /**
     * @brief 输入密码
     * 
     * @param [in] Algorithm : string 算法标识
     * - 参数:
     *  - DES
     *  - SM4
     * .
     * @param [in] IsVoiceAgain : bool [default:false] 是否再次输入
     * @param [in] MkIndex : byte 主密钥索引
     * @param [in] WkIndex : byte 工作密钥索引
     * @param [in] CardNumber : string 帐号信息
     */
    LC_CMD_METHOD(WaitPassword_Ansi98)
    {
        string algorithm = arg["Algorithm"].To<string>();
        bool isAgain = arg["IsVoiceAgain"].To<bool>(false);
        byte mkIndex = arg["MkIndex"].To<byte>();
        byte wkIndex = arg["WkIndex"].To<byte>();
        string tr2 = arg["CardNumber"].To<string>();

        ByteArray sTr2(tr2.c_str(), tr2.length());
        ByteArray trBuff = sTr2;
        for(size_t i = 0;i < sTr2.GetLength(); ++i)
        {
            if(sTr2[i] == '=' || sTr2[i] == '\'')
            {
                trBuff = sTr2.SubArray(0, i);
                break;
            }
        }
        ByteBuilder cardNumber(8);
        ByteBuilder tmp(8);
        Key_Provider::FormatAnsiCardID(trBuff, tmp);
        tmp.RemoveFront(2);
        ByteConvert::ToAscii(tmp, cardNumber);

        if(StringConvert::Compare(algorithm.c_str(), "DES", true))
        {
            if(!_desAdapter.WaitPassword_Ansi98(mkIndex, wkIndex, isAgain, cardNumber))
                return false;
        }
        else if(StringConvert::Compare(algorithm.c_str(), "SM4", true))
        {
            if(!_sm4Adapter.WaitPassword_Ansi98(mkIndex, wkIndex, isAgain, cardNumber))
                return false;
        }
        else
        {
            _logErr(DeviceError::ArgFormatErr, "错误的算法标识");
            return false;
        }
        return true;
    }
    /**
     * @brief 获取输入的密文密码
     * @retval Pwd : hex 获取到的密文密码
     */
    LC_CMD_METHOD(GetPassword_Ansi98)
    {
        ByteBuilder pin(16);
        size_t pinlen = 0;
        if(!_managerAdapter.GetPassword(pin, &pinlen))
            return false;

        ByteBuilder tmp(8);
        ByteConvert::ToAscii(pin, tmp);
        rlt.Put("Pwd", tmp.GetString());
        return true;
    }
    /**
     * @brief 等待用户输入(明文输入密码)
     * @date 2016-05-04 20:37
     * @param [in] IsVoice : bool [default:true] 是否进行语音提示
     */
    LC_CMD_METHOD(InputInformation)
    {
        bool isVoice = arg["IsVoice"].To<bool>(true);
        return _managerAdapter.InputInformation(isVoice);
    }
    /**
     * @brief 评价
     * 
     * @param [in] IsVoice : bool [default:Null] 是否播放语音
     * 
     * @retval EvaluationId : int 评价ID
     * @retval Evaluation : string 评价描述字符 "满意/不满意/非常满意"
     */
    LC_CMD_METHOD(Evaluation)
    {
        string voice = arg["IsVoice"].To<string>();
        PSBC_PinManagerDevAdapter::EvaluationStatus status = PSBC_PinManagerDevAdapter::Unknown;
        // 没有该字段名称
        if(voice.length() < 1)
        {
            if(!_managerAdapter.Evaluation(status))
                return false;
        }
        else
        {
            bool isVoice = ArgConvert::FromString<bool>(voice);
            if(!_managerAdapter.EvaluationVoice(status, isVoice))
                return false;
        }
        
        string evaluationId = ArgConvert::ToString<int>(static_cast<int>(status));
        rlt.Put("EvaluationId", evaluationId);
        rlt.Put("Evaluation", PSBC_PinManagerDevAdapter::EvaluationTostring(status));
        return true;
    }
    /**
     * @brief 生成公钥
     * 
     * @param [in] Algorithm : string 算法标识
     * - 参数:
     *  - RSA
     *  - SM2
     * .
     * @param [in] RsaSize : uint [default:2048] RSA密钥的位数,默认为2048
     * .
     * @retval PublicKey : hex 生成的公钥
     */
    LC_CMD_METHOD(GenerateKEY)
    {
        string algorithm = arg["Algorithm"].To<string>();
        ByteBuilder pk(512);
        if(StringConvert::Compare(algorithm.c_str(), "SM2", true))
        {
            if(!_guomiAdapter.GenerateKEY_SM2(pk))
                return false;
        }
        else if(StringConvert::Compare(algorithm.c_str(), "RSA", true))
        {
            uint bit = arg["RsaSize"].To<uint>(2048);
            if(!_guomiAdapter.GenerateKEY_RSA(bit, pk))
                return false;
        }
        else
        {
            _logErr(DeviceError::ArgFormatErr, "错误的算法标识");
            return false;
        }
        ByteBuilder tmp(512);
        ByteConvert::ToAscii(pk, tmp);
        rlt.Put("PublicKey", tmp.GetString());
        return true;
    }
    /**
     * @brief 生成密钥
     * 
     * @param [in] Algorithm : string 算法标识
     * - 参数:
     *  - DES
     *  - 3DES
     *  - SM2
     *  - SM4
     *  - RSA
     * .
     * @param [in] WkIndex : byte 加密的工作密钥ID
     * @param [in] CardNumber : string 帐号信息
     * @param [in] PadByte : byte [default:0x00] 后补字节
     * @param [in] PinLength : size_t [default:6] 期望输入的密码长度
     * @param [in] IsNeedOK : bool [default:true] 是否需要按回车自动返回
     * @param [in] Timeout : uint [default:DEV_WAIT_TIMEOUT] 超时时间(秒)
     * 
     * @retval PIN : hex 获取到的密文密码
     */
    LC_CMD_METHOD(GeneratePIN)
    {
        string algorithm = arg["Algorithm"].To<string>();
        string sWkIndex = arg["WkIndex"].To<string>();
        string sCardNumber = arg["CardNumber"].To<string>();
        byte padByte = arg["PadByte"].To<byte>(0x00);
        size_t pinLength = arg["PinLength"].To<size_t>(6);
        bool isNeedOk = arg["IsNeedOK"].To<bool>(true);
        uint timeoutS = arg["Timeout"].To<uint>(DEV_WAIT_TIMEOUT);

        // 设置算法
        PSBC_PinPadDevAdapter::AlgorithmMode mode = PSBC_PinPadDevAdapter::UnknownMode;
        ByteArray sMode(algorithm.c_str(), algorithm.length());
        if(StringConvert::Compare(sMode, "DES", true))
        {
            mode = PSBC_PinPadDevAdapter::DES3_Mode;
        }
        else if(StringConvert::Compare(sMode, "3DES", true))
        {
            mode = PSBC_PinPadDevAdapter::DES3_Mode;
        }
        else if(StringConvert::Compare(sMode, "SM2", true))
        {
            mode = PSBC_PinPadDevAdapter::SM2_Mode;
        }
        else if(StringConvert::Compare(sMode, "SM4", true))
        {
            mode = PSBC_PinPadDevAdapter::SM4_Mode;
        }
        else if(StringConvert::Compare(sMode, "RSA", true))
        {
            mode = PSBC_PinPadDevAdapter::RSA_Mode;
        }
        else
        {
            _logErr(DeviceError::ArgFormatErr, "错误的算法标识");
            return false;
        }
        if(!_guomiAdapter.SetAlgorithmMode(mode))
            return false;
        const size_t MAC_KEYID_LENGTH = 13;
        ByteBuilder wkId(MAC_KEYID_LENGTH);
        wkId = sWkIndex.c_str();
        ByteConvert::Fill(wkId, MAC_KEYID_LENGTH, false, '0');
        if(!_guomiAdapter.SetWK_ID(wkId))
            return false;
        if(!_guomiAdapter.SetPinblock(padByte))
            return false;
        if(!_guomiAdapter.SetPinLength(_itobyte(pinLength)))
            return false;

        wkId = sCardNumber.c_str();
        const size_t CARD_LENGTH = 12;
        if(wkId.GetLength() > CARD_LENGTH)
            wkId.RemoveTail();
        ByteConvert::Fill(wkId, CARD_LENGTH, false, '0');
        ByteBuilder pinBlock(8);
        if(!_guomiAdapter.GetPwd(wkId, pinBlock, _itobyte(timeoutS)))
            return false;

        ByteBuilder tmp(8);
        ByteConvert::ToAscii(pinBlock, tmp);
        rlt.Put("PIN", tmp.GetString());
        return true;
    }
    /**
     * @brief 等待按键输入
     * @date 2016-09-29 21:14
     * 
     * @retval Key : string 输入的按键
     * @retval KeyCode : byte 输入的按键编码
     */
    LC_CMD_METHOD(WaitEntry)
    {
        ByteBuilder key(2);
        if(!_pDev->Read(key))
        {
            _logErr(DeviceError::RecvErr, "等待按键失败");
            return false;
        }

        ByteBuilder input(8);
        for(size_t i = 0;i < key.GetLength(); ++i)
        {
            PSBC_PinCmdDriver::FormatInput(key[i], input);
            if(key[i] == 0x0D || key[i] == 0x1B || key[i] == 0x08)
            {
                rlt.Put("Key", input.GetString());
                rlt.Put("KeyCode", ArgConvert::ToString(key[i]));
                break;
            }
        }
        LOGGER(_log<<"Input:<"<<input.GetString()<<">\n");
        return true;
    }
    /**
     * @brief 获取应用序号
     * @date 2017-02-15 15:31
     * 
     * @retval AppNumber : hex 获取到的应用序号
     */
    LC_CMD_METHOD(GetAppNumber)
    {
        ByteBuilder appNumber(8);
        if(!_managerAdapter.GetAppNumber(appNumber))
            return false;
        ByteBuilder tmp(8);
        rlt.Put("AppNumber", ArgConvert::ToString(appNumber));
        return true;
    }
    /**
     * @brief 设置应用序号
     * @date 2017-02-15 15:32
     * 
     * @param [in] AppNumber : hex 需要设置的应用序号
     */
    LC_CMD_METHOD(SetAppNumber)
    {
        string appNumber = arg["AppNumber"].To<string>();
        ByteBuilder tmp(8);
        DevCommand::FromAscii(appNumber.c_str(), tmp);
        return _managerAdapter.SetAppNumber(tmp);
    }
    /**
     * @brief 获取次主密钥ID
     * @date 2017-02-15 16:03
     * 
     * @retval ID : hex 获取到的次主密钥ID
     */
    LC_CMD_METHOD(GetMK_ID)
    {
        ByteBuilder recv(8);
        if(!_guomiAdapter.GetMK_ID(recv))
            return false;
        rlt.Put("ID", ArgConvert::ToString(recv));
        return true;
    }
    /**
     * @brief 设置次主密钥ID
     * @date 2017-02-15 16:03
     * 
     * @param [in] ID : hex 需要设置的次主密钥ID
     */
    LC_CMD_METHOD(SetMK_ID)
    {
        string sID = arg["ID"].To<string>();
        ByteBuilder id(8);
        DevCommand::FromAscii(sID.c_str(), id);
        return _guomiAdapter.SetMK_ID(id);
    }
};
//--------------------------------------------------------- 
} // nemespace driver
} // namespace application
} // namespace zhou_yb
//--------------------------------------------------------- 
#endif // _LIBZHOUYB_PSBC_PINCMDDRIVER_H_
//========================================================= 